package clientCommunicationHandler;

import java.util.ArrayList;
import java.util.List;

import client.TelnetClient;


public class ClientServerMsgHandler {

	public static boolean isReady = false;
	public static boolean buildMenu = true;
	public static String subForumId = "0";
	public static String defultUserMsg = "please make your choice:";
	public static String currentUserMsg = "please make your choice:";

	public ClientServerMsgHandler(){

	}

	public void parseServerMsg(String serverMsg){
		String tMsg = serverMsg;
		//		System.out.println("parsing msg :"+serverMsg);
		String serverCommand;
		if(serverMsg.substring(0, 8).equalsIgnoreCase("postList")){
			serverCommand = tMsg.split((char)1+"")[0];
		}
		else
			 serverCommand = tMsg.split("\n")[0];
		if(serverCommand.equalsIgnoreCase("subForumList")){
			TelnetClient.menu = buildNewViewMenu(tMsg,"viewSubForum");	
		}
		else{
			if(serverCommand.equalsIgnoreCase("threadsList")){
				this.handleThreadListMsg(tMsg);
				TelnetClient.userPosition.add(TelnetClient.tempUserNextPosition);
//				System.out.println("parseServerMsg: position is: "+TelnetClient.userPosition);
			}
			else{
				if(serverCommand.equalsIgnoreCase("postList")){
					this.handlePostListMsg(tMsg);
					TelnetClient.userPosition.add(TelnetClient.tempUserNextPosition);
				}
				else{
					if(serverCommand.equalsIgnoreCase("logout")){
						this.handleLogoutMsg(tMsg);
					}
					else{
						if(serverCommand.equalsIgnoreCase("register")){
							this.loginToSystem(serverCommand,tMsg);
						}
						else{
							if(serverCommand.equalsIgnoreCase("login")){
								this.loginToSystem(serverCommand,tMsg);
							}

							else{
								if(serverCommand.equalsIgnoreCase("addPostMessage")){
//									System.out.println("addedNewPostMesg");
									ClientServerMsgHandler.buildMenu = false;
								}
								else{
									if(serverCommand.equalsIgnoreCase("addedSubForum")){
										BuildAddedSubForumMenu(tMsg);
									}
										else{
											if(serverCommand.equalsIgnoreCase("candidatesList")){
												buildCandidatesListMenu(tMsg);
											}
											else{
												if(serverCommand.equalsIgnoreCase("moderatorsList")){
													buildViewModeratorsList(tMsg);
												}
											}
												
										}
								}
							}
						}
					}
				}
			}
		}
		
		this.buildUserUpdatedMenu(serverCommand);
	}

	private void buildViewModeratorsList(String tMsg) {
		String[] command = tMsg.split("\n");
		StringBuilder tempMenu = new StringBuilder();
		ClientServerMsgHandler.currentUserMsg = "moderators of subForum: "+ClientServerMsgHandler.subForumId+":";
		int startNamesIndex = 2;
		getPeopleNamesSeparatedByNewLine(command, tempMenu, startNamesIndex,true);
		tempMenu.append("\n\t1. back");
		UserInterfaceMsgHandler.goingToRemoveModerator  = true;
	}

	private void buildCandidatesListMenu(String tMsg) {
		String[] command = tMsg.split("\n");
		StringBuilder tempMenu = new StringBuilder();
		ClientServerMsgHandler.currentUserMsg = "choose new moderator for sub forum "+ClientServerMsgHandler.subForumId+":";
		int startNamesIndex = 2;
		getPeopleNamesSeparatedByNewLine(command, tempMenu, startNamesIndex,false);
		tempMenu.append("\n\t1. back");
	}

	private void getPeopleNamesSeparatedByNewLine(String[] command,
			StringBuilder tempMenu, int startNamesIndex,boolean remove) {
		int numberOfCandidateModerators = command.length - startNamesIndex;
		String[] moderators = new String[numberOfCandidateModerators];
		System.arraycopy(command, startNamesIndex, moderators, 0, numberOfCandidateModerators);
		getPossiableModeratorListed(moderators, tempMenu,remove);
		TelnetClient.menu = tempMenu;
	}

	private void BuildAddedSubForumMenu(String tMsg) {
		String[] command = tMsg.split("\n");
		ClientServerMsgHandler.subForumId = command[3];
		StringBuilder tempMenu = new StringBuilder();
		tempMenu.append("choose new moderator for sub forum "+ClientServerMsgHandler.subForumId+":");
		int numberOfCandidateModerators = command.length - 4;
		String[] moderators = new String[numberOfCandidateModerators];
		System.arraycopy(command, 4, moderators, 0, numberOfCandidateModerators);
		getPossiableModeratorListed(moderators, tempMenu,false);
		TelnetClient.menu = tempMenu; 
		
	}

	private void getPossiableModeratorListed(String[] moderatorsNames,
			StringBuilder tempMenu,boolean remove) {
		int counter = 1;
		for(int i = 0 ; i <moderatorsNames.length;i++){
			if (remove)
				tempMenu.append("\n\t"+counter+". remove "+moderatorsNames[i]);
			else
				tempMenu.append("\n\t"+counter+". "+moderatorsNames[i]);
			counter++;
		}
		
	}

	private void buildUserUpdatedMenu(String serverCommand) {
		if(!(serverCommand.equals("addThread"))){
			if(!serverCommand.equals("addedSubForum"))
			TelnetClient.menu = new StringBuilder("[user: "+TelnetClient.userName+"] "+ClientServerMsgHandler.currentUserMsg+"\n\t1. "+
					(TelnetClient.userName.equalsIgnoreCase("guest")? "Login\n\t2. Register\n":"Logout\n")+
					getRestOfTheMenu(TelnetClient.userName.equalsIgnoreCase("guest")? 3:2));
			
			synchronized (ClientServerMsgHandler.class) {
				if(ClientServerMsgHandler.buildMenu == true){//to ensure that new login user will see the correct menu
					isReady = true;

					ClientServerMsgHandler.class.notifyAll();
				}
				else {
					ClientServerMsgHandler.buildMenu = true;
				}
			}
		}
		ClientServerMsgHandler.currentUserMsg = ClientServerMsgHandler.defultUserMsg;
	}

	private void handleLogoutMsg(String tMsg) {
		TelnetClient.userName = "guest";
		TelnetClient.menu = TelnetClient.welcom_page;	
	}

	private void handlePostListMsg(String tMsg) {
		TelnetClient.menu = buildNewViewPosts(tMsg,"viewThread");
		//TelnetClient.userPosition.add(TelnetClient.tempUserNextPosition);
	}
	private StringBuilder buildNewViewPosts(String tMsg, String string) {
		String [] splitedMsg = tMsg.split((char)1+"");
		StringBuilder tSb = new StringBuilder();
		String userRoll;
		int counter = 2 ;
		List<String> postsIds = new ArrayList<String>();
		for(int i = 2 ;i< splitedMsg.length -1;i++){
			String [] postMsgFormat = splitedMsg[i].split((char)2+"");
			userRoll = postMsgFormat[1];
			boolean canEditMsg = userRoll.equalsIgnoreCase("admin") || userRoll.equalsIgnoreCase("moderator")|| userRoll.equalsIgnoreCase("owner");
			String postSubject = postMsgFormat[0];
			String postBody = postMsgFormat[2];
			String postId = postSubject.split(":")[0];
			postsIds.add(postId);
			tSb.append("\n\t"+counter+". post "+postSubject+" content: "+ postBody);
			counter++;
			if(canEditMsg == true){
				tSb.append("\n\t"+counter+". removePost "+postSubject);
				counter++;
				tSb.append("\n\t"+counter+". editPost "+postSubject);
				counter++;
			}
		}
		//allow to add a new msg if the user is not a guest and his current possition is not sub-Forum 
		if(!(TelnetClient.userName.equals("guest"))){
			for (String id : postsIds) {
				tSb.append("\n\t"+counter+". "+"addPost " + id);
				counter++;
			}
		}
		tSb.append("\n\t"+counter +". "+"back\n");
		return tSb;
	}


	private String getPostId(String string) {
		String [] tempArray = string.split(":");
		return tempArray[0];
	}

	private void handleThreadListMsg(String tMsg) {
		TelnetClient.menu = buildNewViewMenu(tMsg,"viewThreads");
		//				TelnetClient.SubForumId = Integer.parseInt(tMsg.split("\n")[1]);
		while(TelnetClient.userPosition.size() > 1)
			TelnetClient.userPosition.remove(TelnetClient.userPosition.size() -1);
		
	}

	/**
	 * 
	 * @param tMsg the server msg
	 * @param view king of view we want to send
	 * @return
	 */
	public StringBuilder buildNewViewMenu(String tMsg,String view) {
		String [] subForumList = tMsg.split("\n");
		String userRoll = subForumList[1];
		boolean canEditMsg = userRoll.equalsIgnoreCase("admin") || userRoll.equalsIgnoreCase("owner") ||userRoll.equalsIgnoreCase("moderator");
		StringBuilder tSb = new StringBuilder();
		int counter = 1 ; 
		for(int i=2;i<subForumList.length;i++){
			tSb.append("\n\t"+counter+". "+view+" "+subForumList[i]);
			counter++;
		}

		//allow to add a new msg if the user is not a guest and his current possition is not sub-Forum 
		if((!(TelnetClient.userName.equals("guest")) && !view.equals("viewThreads"))){
			tSb.append("\n\t"+counter+". "+"add");
			counter++;
			if(canEditMsg){
				tSb.append("\n\t"+counter+". "+"editMsg");
				counter++;
				tSb.append("\n\t"+counter+". "+"deleteMsg");
				counter++;
			}
		}
		if(userRoll.equalsIgnoreCase("admin") && view.equals("viewThreads")){
			int numberOfSubForums = subForumList.length - 2;
			int tempCounter = counter;
			tSb.append(moderatorsAction(counter));
			counter+=tempCounter;
			tSb.append(DeleteSubForum(counter,numberOfSubForums));
			counter+=tempCounter;
			tSb.append("\n\t"+counter+". "+"add-new-SubForum");
			counter++;
			tSb.append("\n\t"+counter+". "+"moderatorList");
			counter++;
		}
		if(!view.equals("viewThreads")){
			tSb.append("\n\t"+counter +". "+"back\n");
//			System.out.println("addin back "+view+"end");
		}
//		System.out.println("returned "+tSb);
		return tSb;
	}
	private String DeleteSubForum(int counter, int numberOfSubForums) {
		int index = 1;
		StringBuilder sb = new StringBuilder();
		while(index <= numberOfSubForums){
			sb.append("\n\t"+(counter+index-1)+". "+"DeleteSubForum "+index);
			index++;
		}

		return sb.toString();
	}

	private String moderatorsAction(int currentIndex) {
		int subForumid = 0;
		int menuIndex = 0 ;
		int counter = currentIndex -1 ;
		StringBuilder sb = new StringBuilder();
		while(subForumid < counter){
			sb.append("\n\t"+(currentIndex+menuIndex)+". "+"add-moderator to subForum "+(counter-subForumid));
			menuIndex++;
			sb.append("\n\t"+(currentIndex+menuIndex)+". "+"remove-moderator of subForum "+(counter-subForumid));
			menuIndex++;
			subForumid++; 
			
		}

		return sb.toString();
	}

	/***
	 * 
	 * @param i 2 if user loged in 3 if user in a guest mode
	 * @return rest of the menu without login/logout/register
	 */
	public String getRestOfTheMenu(int i) {
		String[] tSplitMenu = TelnetClient.menu.toString().split("\n\t");
		StringBuilder tempResult = new StringBuilder();
		
		int tCounter = i;
		for(int j=1;j<tSplitMenu.length;j++){
			if(!(tSplitMenu[j].split(" ")[1].equalsIgnoreCase("login")||tSplitMenu[j].split(" ")[1].equalsIgnoreCase("register")||tSplitMenu[j].split(" ")[1].equalsIgnoreCase("logout"))){
				int dotPosition = tSplitMenu[j].indexOf(" ")+1;
				if( j == tSplitMenu.length-1 )
					tempResult.append("\t"+tCounter+". "+tSplitMenu[j].substring(dotPosition));
				else
					tempResult.append("\t"+tCounter+". "+tSplitMenu[j].substring(dotPosition)+"\n");
				tCounter++;
			}
		}
		return tempResult.toString();
	}
	/**
	 * 
	 * @param serverCommand if connection was success or not 
	 * @param serverMsg
	 * @return
	 */
	private String loginToSystem(String serverCommand,String serverMsg){
//		System.out.println("login to system");
		String success = serverMsg.split("\n")[1];
		String tMsg = serverCommand;
		if(!success.equals("guest")){
			TelnetClient.userName = TelnetClient.tempUserName;
			TelnetClient.menu = new StringBuilder("[user: "+TelnetClient.userName+"] "+TelnetClient.menu);
		}
		else{
			tMsg = new String("your "+(serverCommand.equalsIgnoreCase("login")?"login":"registration")+" failed: "+serverMsg.split("\n")[3]);
			TelnetClient.menu = new StringBuilder(tMsg + TelnetClient.menu);
		}
//		System.out.println(tMsg);
		return tMsg;
	}

}
